#!/usr/bin/env ruby
#
#
# SleepMirror - A view on your sleep quality.
#
# This prototype will load or accept an image and slowly fade it in.
# Text is written giving the user instructions on what to do.
# Start time is captured.
# Keyboard (SDL) Events are examined, looking for :t or :f.
# End time is captured and elapsed time is computed.
# The key pressed triggers a message sayingcorrect or incorrect.
# The elapsed time is displayed.
# Then we loop until q, esc, or quit is requested.
#
# Version History:
# 01/18/2010 cgm: initial version.
# 01/19/2010 cgm p3: Refactor this code into classes, remove the globals.
#
#Note to Self:  The OCRA build command is
#C:\Users\Gary\Documents\NetBeansProjects\sleepmirror\lib>ocra SleepMirror.rb * images\* 

main_dir = File.dirname(__FILE__)                  #get the directory we're in

Dir.chdir main_dir  # force the working directory to be where the script resides.  This is for Ocra expansion.

#add the relative paths to find SDL before we include rubygame. Expect it to be "...Temp/ocrxxx.tmp/src/dlls"
#TODO: Enable this once you figure out why it isn't working.
#TODO: In the meantime, put all dlls and images in the same directory as the main script
#SDL_PATHS = [ File.join( main_dir, "dlls" ) ]

require "rubygame"
include Rubygame
include Rubygame::Events
include Rubygame::EventTriggers
include Rubygame::EventActions


# Initialize Rubygame, and clean up when script exits.
Rubygame.init
at_exit { Rubygame.quit }

DEFAULT_IMAGE = "Eq135.png" # this is the default image to load if one is not provided on the command line.
# Decide which image file to load.
this_dir = File.dirname( __FILE__ )
file = File.expand_path( DEFAULT_IMAGE, this_dir ) # default file
if ARGV[0]
  file = File.expand_path( ARGV[0], this_dir )
else
  puts "You can pass an script to this file to load it."
end

MAXALPHA = 255 # Maximum alpha value
ALPHASTEP = 1  # How much to dim/brighten the image
MINALPHA = 0   # Mimimum alpha value

# Wrap this code in a "begin/rescue" block to recover from errors if
# the image cannot be loaded.
#
begin

  # Load the image
  $image = Surface.load( file )
  $image.colorkey=$image.get_at([0,0])
  $image.alpha=0

  # Open a new Rubygame window to fit the image.
  $screen = Screen.open( $image.size,0,[HWSURFACE] )
  $screen.title = "SleepMirror-prototype with " + File.basename(file)
  $screen.fill($image.colorkey) #Fill the screen with the image's background

=begin
  # Setup a clock to set framerate
  $clock = Clock.new
  $clock.target_framerate=(32)
  $clock.enable_tick_events
  $clock.calibrate
=end

  # Blit ("paste") the image onto the screen.
  $image.blit( $screen, [0,0] )

rescue SDLError, NoMethodError

  # Oops, load failed.
  puts "#{File.basename($0)}: Could not load image: #{file}"

  # Open a new Rubygame window
  $screen = Screen.open( [200,200] )
  $screen.title = "Load Error"

  # Fill with white
  $screen.fill( :white )

  # Thick red line from top left to bottom right.
  # Point [0,0] is the top left corner of the screen,
  # [200,200] is bottom right.
  #
  $screen.draw_polygon_s( [[ -5,   5], [  5,  -5],
                          [205, 195], [195, 205]], :red )

  # Now from top right to bottom left.
  $screen.draw_polygon_s( [[195,  -5], [205,   5],
                          [  5, 205], [ -5, 195]], :red )

end


# Set up an event handler to listen for events:
#
#  - Q or Escape keys press
#  - Right mouse click inside the window
#  - Window close button press
#
# When any of these events occurs, the "exit_script" method is called.
#
class MyHandler
  include Rubygame::EventHandler::HasEventHandler
end

handler = MyHandler.new
handler.make_magic_hooks( :q            => :exit_script,
                          :escape       => :exit_script,
                          :mouse_right  => :exit_script,
                          QuitRequested => :exit_script
                          #:f            => :show_time,
                          #:t            => :show_time
                        )
is_false_hook = EventHook.new( :owner => nil,
                               :trigger => KeyPressTrigger.new(:f),
                               :action  => MethodAction.new(:show_time))
is_true_hook = EventHook.new(  :owner => nil,
                               :trigger => KeyPressTrigger.new(:t),
                               :action  => MethodAction.new(:show_time))
handler.append_hook(is_false_hook) #Add the T/F hooks to the event table
handler.append_hook(is_true_hook) #Add the T/F hooks to the event table

def make_dim
 $screen=Screen.new($image.size,0,[HWSURFACE])
 $screen.fill($image.colorkey)
 $image.alpha < ALPHASTEP ? $image.alpha=MINALPHA : $image.alpha -= ALPHASTEP
 $image.blit($screen,[0,0])
 puts "Dim: Image alpha now #{$image.alpha}"
end
def make_bright
  $screen=Screen.new($image.size,0,[HWSURFACE])
  $screen.fill($image.colorkey)
  $screen.show_cursor=FALSE
  $image.alpha > MAXALPHA-ALPHASTEP ? $image.alpha=MAXALPHA : $image.alpha += ALPHASTEP
  $image.blit($screen,[0,0])

  TTF.setup()
  ttfont_path = File.join(File.dirname(__FILE__),"FreeSans.ttf")
  ttfont = TTF.new( ttfont_path, 30 )
  result = ttfont.render( "A simple equation will appear soon. Press T for True or F for False",true,:blue)
  result.blit( $screen,[$image.size[0]/2-result.size[0]/2,5])
  #puts "Brighten: Image alpha now #{$image.alpha}"
end
def show_time (event)
  elapsed_time = Time.now - $t
  $answered = true
  puts "Elapased time #{elapsed_time}s"
  TTF.setup()
  ttfont_path = File.join(File.dirname(__FILE__),"FreeSans.ttf")
  ttfont = TTF.new( ttfont_path, 24 )
  result = ttfont.render( "You chose #{event.key.upcase}; that is #{event.key==:f ? "Correct!" : "incorrect."} Your time was #{elapsed_time}s.  Press Q or ESC to quit.", true, :white )
  result.blit( $screen,[$image.size[0]/2-result.size[0]/2,$image.size[1]/2])
end
def exit_script
  #elapsed_time = Time.now - $t
  #puts "Elapased time #{elapsed_time}s"
  exit
end

$t=Time.now #Capture the starting time.

$answered = false # Repeat this code until the user provides an answer.
until $answered do
#loop do

  # Fetch the user input events from SDL.
  events = Rubygame::Events.fetch_sdl_events
  events << make_bright

  # Pass each input to the event handler to check.
  events.each do |event|
    handler.handle( event )
  end

  #$clock.tick

  # Refresh the screen
  $screen.update()

  # Pause for a while before checking for more events.
  sleep 0.1

end

#loop again until user signals exit
handler.remove_hook(is_false_hook) #Remove the hooks that cause the elapsed time to update
handler.remove_hook(is_true_hook) #This leaves on the hooks to exit on the event table

loop do
  events = Rubygame::Events.fetch_sdl_events
  events.each do |event|
    handler.handle( event )
  end
end

